<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>高阶函数及函数柯里化</title>
</head>

<body>
    <script>
        /**
         * 高阶函数及函数柯里化
         *  一个函数返回一个函数
            一个函数可以参数接受一个函数
            这两个条件满足任意一个均可 ，promise内部肯定也是回调函数 （内部包含这高阶函数）。
        */
        // 扩展方法 会用到高阶函数 
        // function core(...args) {
        //     // 剩余运算符
        //     // .... 前面增加的逻辑
        //     console.log('core', args)
        //     // .. 之后增加的逻辑
        // }

        // // 给core函数增加一些额外的逻辑 但是不能更改核心代码
        // Function.prototype.before = function (cb) {
        //     return (...args) => {
        //         // newCore 剩余运算符 可以把多个参数转化成数组
        //         cb();
        //         this(...args) // 扩展运算符
        //     }
        // }
        // // core作为实例对象，它的隐式原型__proto__为Function
        // function F() { }
        // // core F 都是由构造函数Function创建Function.__proto__与Function.prototype是同一个值ƒ () { [native code] }
        // console.log(core.__proto__ === Function.__proto__, Function.prototype, Function.__proto__, F.__proto__.constructor)// trur, ƒ () { [native code] } ƒ () { [native code] }
        // console.log(Function.__proto__.__proto__)//object的原型对象
        // console.log(Function.__proto__.__proto__.__proto__)// null   object的原型对象的__proto__为null
        // console.log(Object.__proto__ === Function.__proto__) // true
        // let newCore = core.before(() => {
        //     console.log('before')
        // })
        // newCore('a', 'b')
        /**
        * 函数柯里化的概念
        *  函数柯里化：多个参数的传入，把他转化成 n个函数，可以暂存变量(主要用于缓存，将参数缓存到代码中，在返回一个新的函数直到参数都传递完成后调用最后的函数)
           一般柯里化参数的要求都是一个个的传 ==》多个参数传入就是偏函数
           实现通用的函数柯里化
       */
        // function curring(fn) {
        //     const inner = (args = []) => {
        //         return args.length >= fn.length ? fn(...args) : (...userArgs) => inner([...args, ...userArgs])
        //     }
        //     return inner()
        // }
        /**
         * 案例实现add(1)(2)(3)(4)
        */ 
        function add(num) {
            var sum = 0;
            sum = sum + num;
            return function tempFun(numB) {
                if (arguments.length === 0) {
                    // 当参数为空的时候输出具体的值
                    return sum;
                } else {
                    sum = sum + numB;
                    return tempFun;//参数不为空的时候进行函数递归返回
                }
            }
        }
        var result = add(2)(3)(4)(5)();
        console.log(result);//输出14

    </script>
</body>

</html>